﻿using IOA.MES.Client.Common;
using IOA.MES.Client.Models.Response;
using IOA.MES.Client.Settings;
using IOA.MES.Common;
using Newtonsoft.Json;
using NLog;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Diagnostics;
using System.Reflection;

namespace IOA.MES.Client.ELMid
{
    /// <summary>
    /// ELMidIndex.xaml 的交互逻辑
    /// </summary>
    public partial class ELMidIndex : Window
    {
        private List<ViaSiteRecord> _records { get; set; } = new List<ViaSiteRecord>();
        private List<KeyValuePair<int, string>> fileChanges { get; set; } = new List<KeyValuePair<int, string>>();
        private List<string> qLevels = new List<string>();
        private string curImage = string.Empty;
        private FileSystemWatcher watcher;
        private string curDirectory;
        private WinELMidTip winEL1Tip;

        public ELMidIndex()
        {
            InitializeComponent();
        }


        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrWhiteSpace(BaseEnv.UserInfo.FtpConfig?.FtpRoot) || string.IsNullOrWhiteSpace(BaseEnv.UserInfo.FtpConfig?.UserName) || string.IsNullOrWhiteSpace(BaseEnv.UserInfo.FtpConfig?.Password))
            {
                CommonMessage.Alert(this, "请在系统设置中配置文件上传地址\r\nPlease configure the file upload address in the system settings", false);
                this.Close();
            }

            txtTrueName.Text = BaseEnv.UserInfo.TrueName;
            var folder = BaseEnv.GetStorage("ElMidMonitorFolder");
            if (Directory.Exists(folder))
            {
                WatcherStrat(folder);
            }
            winEL1Tip = new WinELMidTip();
            winEL1Tip.Show();
            winEL1Tip.Topmost = true;

            InitDuties();
            InitMachines();
            InitQLevels();
            InitRecords();
        }


        #region 初始化数据
        public void InitDuties()
        {
            var duties = BaseEnv.InvokeApi<QueryDutiesResponse>("/api/Auth/QueryDuties", new { }).Data.Duties;

            cbDuties.ItemsSource = duties;
            cbDuties.DisplayMemberPath = "DutyName";
            cbDuties.SelectedValuePath = "DutyId";

            if (duties.Any())
            {
                cbDuties.SelectedIndex = 0;
            }
        }

        public void InitMachines()
        {
            var machines = BaseEnv.InvokeApi<QueryMachinesResponse>("/api/Machine/QueryMachines", new { MachineType = MachineType.NQC }).Data.Machines;
            cbMachines.ItemsSource = machines;
            cbMachines.DisplayMemberPath = "MachineName";
            cbMachines.SelectedValuePath = "MachineId";

            if (machines.Any(_ => _.MachineId == BaseEnv.MachineId))
            {
                cbMachines.SelectedIndex = machines.FindIndex(_ => _.MachineId == BaseEnv.MachineId);
            }
            else
            {
                CommonMessage.Alert(this, "Vui lòng chọn lại thiết bị trong cài đặt hệ thống ngay bây giờ\r\n请先在系统设置中重新选择设备\r\nPlease reselect the device in the system settings now"); ;
                new SettingsIndex().ShowDialog();
            }
        }

        private void InitRecords()
        {
            new TaskFactory().StartNew(() =>
            {
                Thread.Sleep(100);
                Dispatcher.Invoke(new Action(() =>
                {
                    var response = BaseEnv.InvokeApi<QueryViaSiteRecordsResponse>("/api/Machine/QueryViaSiteRecords", new { DutyId = Convert.ToInt32(cbDuties.SelectedValue), SiteType = SiteType.EL1, MachineId = Convert.ToInt32(cbMachines.SelectedValue) });
                    if (response.ErrCode != 200)
                    {
                        CommonMessage.Alert(this, response.ErrMsg);
                        return;
                    }
                    _records.Clear();
                    _records.AddRange(response.Data.Records);
                    _records.ForEach(_ => _.No = _records.Count - _records.IndexOf(_));
                    BindGridRecords();
                }));
            });
        }

        private void BindGridFileChanges(string content)
        {
            fileChanges.Insert(0, new KeyValuePair<int, string>(fileChanges.Count + 1, content));
            gridFileChanges.ItemsSource = null;
            gridFileChanges.ItemsSource = fileChanges;
        }

        private void BindGridRecords()
        {
            gridRecords.ItemsSource = null;
            gridRecords.ItemsSource = _records;
            lbTotal.Content = _records.Select(_ => _.Code.ToUpper().Trim()).Distinct().Count();
        }

        public void InitQLevels()
        {
            qLevels = BaseEnv.InvokeApi<QueryQLevelsResponse>("/api/NQC/QueryLevels", new { }).Data.Levels;
            if (qLevels.Count < 2)
            {
                CommonMessage.Alert(this, "Hệ thống cần được cấu hình với ít nhất hai cấp độ phán đoán trở lên, vui lòng liên hệ với nhân viên kỹ thuật\r\n系统需要至少配置2个以上判定等级，请联系工艺人员\r\nThe system needs to be configured with at least two or more judgment levels, please contact the technical staff");
                Environment.Exit(0);
            }
        }
        #endregion


        private void cb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            InitRecords();
        }

        private void btnSelectFolder_Click(object sender, RoutedEventArgs e)
        {
            var dialog = new System.Windows.Forms.FolderBrowserDialog();
            if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK && Directory.Exists(dialog.SelectedPath))
            {
                BaseEnv.SetStorage("ElMidMonitorFolder", dialog.SelectedPath);
                WatcherStrat(dialog.SelectedPath);
            }
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (watcher != null)
            {
                watcher.EnableRaisingEvents = false;
                watcher.Dispose();
            }
            if (winEL1Tip != null && PresentationSource.FromVisual(winEL1Tip) != null)
            {
                winEL1Tip.Close();
            }
        }

        private void WatcherStrat(string folder)
        {
            txtFolder.Text = folder;
            BaseEnv.SetStorage("ElMidMonitorFolder", folder);

            if (watcher == null)
            {
                watcher = new FileSystemWatcher();
            }
            watcher.Path = folder;
            watcher.IncludeSubdirectories = true;
            watcher.Created += new FileSystemEventHandler(OnProcess);
            watcher.NotifyFilter = NotifyFilters.Attributes | NotifyFilters.CreationTime | NotifyFilters.DirectoryName | NotifyFilters.FileName | NotifyFilters.LastAccess
                                   | NotifyFilters.LastWrite | NotifyFilters.Security | NotifyFilters.Size;
            watcher.EnableRaisingEvents = true;
        }

        private void OnProcess(object source, FileSystemEventArgs e)
        {
            if (!CheckImageValid(e.FullPath))
            {
                return;
            }

            Dispatcher.Invoke(new Action(() =>
            {
                curImage = e.FullPath;
                txtCode.Text = System.IO.Path.GetFileNameWithoutExtension(e.FullPath).Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries)[0];
                BindGridFileChanges($"监控到：{e.ChangeType}：{e.Name}");

                TryViaSite();
            }));
        }

        private void txtCode_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter && !string.IsNullOrWhiteSpace(txtCode.Text.Trim()))
            {
                TryViaSite();
            }
        }

        private void TryViaSite()
        {
            try
            {
                var imagePath = curImage;
                if (string.IsNullOrWhiteSpace(imagePath) || !File.Exists(imagePath) || !CheckImageValid(imagePath)
                    || !System.IO.Path.GetFileNameWithoutExtension(imagePath).StartsWith(txtCode.Text.Trim(), StringComparison.CurrentCultureIgnoreCase))
                {
                    //先找到当前条码的文件
                    var files = Directory.GetFiles(txtFolder.Text, "*", SearchOption.AllDirectories)
                        .Where(_ => System.IO.Path.GetFileNameWithoutExtension(_).StartsWith(txtCode.Text.Trim(), StringComparison.CurrentCultureIgnoreCase) && CheckImageValid(_)).ToList();

                    if (!files.Any())
                    {
                        CommonMessage.Alert(this, $"EL图片不存在\r\nEL picture does not exist", false);
                        return;
                    }
                    imagePath = files.OrderByDescending(_ => new FileInfo(_).LastWriteTime).FirstOrDefault();
                }

                var elResult = imagePath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries)[imagePath.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).Length - 2].ToUpper();

                var viaSiteRequest = new
                {
                    SiteType = (int)SiteType.NQC,
                    DutyId = Convert.ToInt32(cbDuties.SelectedValue),
                    MachineId = Convert.ToInt32(cbMachines.SelectedValue),
                    Code = txtCode.Text.Trim(),   
                    BadReason= string.Equals(elResult, "OK", StringComparison.CurrentCultureIgnoreCase) ? "" : elResult,
                    Images = new List<string> { }
                };
                try
                {
                    var getComponentResponse = BaseEnv.InvokeApi<GetComponentResponse>("/api/Machine/GetComponent", new { BarCode = txtCode.Text.Trim() });
                    if (getComponentResponse.ErrCode != 200)
                    {
                        mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Fail.wav");
                        mediaElResult.Play();
                        CommonMessage.Alert(this, getComponentResponse.ErrMsg, false);
                        return;
                    }
                    else if (getComponentResponse.Data == null || getComponentResponse.Data.Component == null)
                    {
                        mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Fail.wav");
                        mediaElResult.Play();
                        CommonMessage.Alert(this, $"组件不存在\r\nComponent does not exist：\r\n{txtCode.Text.Trim()}", false);
                        return;
                    }
                    if (winEL1Tip != null && PresentationSource.FromVisual(winEL1Tip) != null)
                    {
                        winEL1Tip.SetComponent(getComponentResponse.Data.Component);
                    }

                    var tmpDirectory = $"/{BaseEnv.WorkshopCode}/elMid/{getComponentResponse.Data.Component.WorkOrderNo}";
                    if (string.IsNullOrWhiteSpace(curDirectory) || !string.Equals(curDirectory, tmpDirectory, StringComparison.CurrentCultureIgnoreCase))
                    {
                        new FtpUtils(BaseEnv.UserInfo.FtpConfig.FtpRoot, BaseEnv.UserInfo.FtpConfig.UserName, BaseEnv.UserInfo.FtpConfig.Password).CheckAndCreateDirectory(tmpDirectory);
                        curDirectory = tmpDirectory;
                    }
                    var fileName = $"{curDirectory}/{System.IO.Path.GetFileName(imagePath)}";
                    Thread.Sleep(2000);
                    new FtpUtils(BaseEnv.UserInfo.FtpConfig.FtpRoot, BaseEnv.UserInfo.FtpConfig.UserName, BaseEnv.UserInfo.FtpConfig.Password).Upload(File.ReadAllBytes(imagePath), fileName);
                    viaSiteRequest.Images.Add($"{BaseEnv.UserInfo.FtpConfig.FtpRoot}{fileName}");
                    BindGridFileChanges($"图片上传完成：{fileName}");
                }
                catch (Exception ex)
                {
                    CommonMessage.Alert(this, $"图片上传失败，请重新拍照\r\nPicture upload failed, please take a new picture\r\n{ex.Message}", false);
                    return;
                }
                CommonMessage.Log(LogLevel.Info, $"条码：{txtCode.Text.Trim()}，结果：{elResult}，图片：{JsonConvert.SerializeObject(viaSiteRequest.Images)}");


                var response = BaseEnv.InvokeApi<ViaSiteResponse>("/api/Machine/ViaSite", viaSiteRequest);
                if (response.ErrCode != 200)
                {
                    mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Fail.wav");
                    mediaElResult.Play();
                    CommonMessage.Alert(this, response.ErrMsg, false);
                    return;
                }

                mediaElResult.Source = new Uri($"{BaseEnv.LocalDirectory}\\res\\audio\\Success.wav");
                mediaElResult.Play();

                CommonMessage.Log(LogLevel.Info, $"过站成功：{txtCode.Text.Trim()}");

                if (response.Data.DutyId != Convert.ToInt32(cbDuties.SelectedValue))
                {
                    cbDuties.SelectedValue = response.Data.DutyId;
                }
                else
                {
                    response.Data.ViaSiteRecord.No = _records.Count + 1;
                    _records.Insert(0, response.Data.ViaSiteRecord);
                    BindGridRecords();
                }

            }
            catch (Exception ex)
            {
                CommonMessage.Alert(this, $"过站失败，请拍照发给IT，并重新尝试过站\r\nPassing failed, please take a picture and send it to IT\r\n{ex.ToString()}", false);
            }
        }

        private bool CheckImageValid(string fileName)
        {
            var nameSplits = fileName.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            if ( !new List<string> { "jpg", "jpeg", "png", "bmp" }.Contains(System.IO.Path.GetExtension(fileName).TrimStart('.'), StringComparer.CurrentCultureIgnoreCase))
            {
                return false;
            }
            return true;
        }

        private void Menu_Click(object sender, RoutedEventArgs e)
        {
            switch (((MenuItem)sender).Name)
            {
                case "btnSettings":
                    new SettingsIndex().ShowDialog();
                    break;
                case "btnMissingRecords":
                    new MissingSiteRecord(Convert.ToInt32(cbMachines.SelectedValue)).Show();
                    break;
                case "btnLogout":
                    new LoginWindow(false).Show();
                    this.Hide();
                    break;
                case "btnAbout":
                    MessageBox.Show($"AISUN Mes Product Version:{FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion}");
                    break;
            }
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            Environment.Exit(0);
        }
    }
}
